package code.extract;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Fang Lu, fanglupku@gmail.com
 */

public class HTMLEntityTransform {
	private static HashMap<Integer, String> ID_Name = new HashMap<Integer, String>();
	private static HashMap<Integer, String> ID_Result = new HashMap<Integer, String>();
	private static HashMap<String, Integer> Name_ID = new HashMap<String, Integer>();

	static {
		ID_Name.put(new Integer(34), "&quot;");
		ID_Name.put(new Integer(38), "&amp;");
		ID_Name.put(new Integer(60), "&lt;");
		ID_Name.put(new Integer(62), "&gt;");
		ID_Name.put(new Integer(160), "&nbsp;");
		
		ID_Result.put(34, "\"");
		ID_Result.put(38, "&");
		ID_Result.put(60, "<");
		ID_Result.put(62, ">");
		ID_Result.put(160, " ");
		
		Name_ID.put("&quot;", new Integer(34));
		Name_ID.put("&amp;", new Integer(38));
		Name_ID.put("&lt;", new Integer(60));
		Name_ID.put("&gt;", new Integer(62));
		Name_ID.put("&nbsp;", new Integer(160));
	}
	public static int getIDByName(String name){
		int result = -1;
		if (Name_ID.containsKey(name)){
			result = Name_ID.get(name).intValue();
		}
		return result;
	}
	public static String getNameByID(int id){
		String result = null;
		if (ID_Name.containsKey(id)){
			result = ID_Name.get(id);
		}
		return result;
	}
	public static String getResultByID(int id){
		String result = null;
		if (ID_Result.containsKey(id)){
			result = ID_Result.get(id);
		}
		return result;
	}
	public static String getResultByName(String name){
		String result = null;
		int id = getIDByName(name);
		if (id != -1){
			result = getResultByID(id);
		}
		return result;
	}
	public static ArrayList<String> stringBatchTransform(ArrayList<String> srcList, ArrayList<String> destList){
		if (destList == null){
			destList = new ArrayList<String>();
		}
		if (srcList != null){
			for (int i=0; i<srcList.size(); ++i){
				destList.add(getResultString(srcList.get(i)));
			}
		}
		return destList;
	}
	public static ArrayList<SegmentItem> segmentItemBatchTransform(ArrayList<SegmentItem> srcList, ArrayList<SegmentItem> destList){
		if (destList == null){
			destList = new ArrayList<SegmentItem>();
		}
		if (srcList != null){
			for (int i=0; i<srcList.size(); ++i){
				SegmentItem thisSeg = new SegmentItem(srcList.get(i));
				thisSeg.setContent(getResultString(thisSeg.getContent()));
				destList.add(thisSeg);
			}
		}
		return destList;
	}
	public static String getResultString(String originString){
		String str_pattern = "&((#[0-9]+?)|([a-z]+?));";
		Pattern pattern = Pattern.compile(str_pattern);
		Matcher matcher = pattern.matcher(originString);
		StringBuffer sb = new StringBuffer();
		int this_start_pos = 0;
		int this_end_pos = 0;
//		int last_start_pos = 0;
		int last_end_pos = 0;
		while (matcher.find()){
			this_start_pos = matcher.start();
			this_end_pos = matcher.end();
			sb.append(new String(originString.substring(last_end_pos, this_start_pos)));
			String this_entity = new String(originString.substring(this_start_pos, this_end_pos));
			if (this_entity.charAt(1) == '#'){
				int this_id = -1;
				try{
					this_id = Integer.parseInt(new String(this_entity.substring(2, this_entity.length()-1)));
					String this_result = getResultByID(this_id);
					if (this_result != null){
						sb.append(this_result);
					} else if (this_id <= Character.MAX_VALUE && this_id >= Character.MIN_VALUE){
						char temp_char = (char)this_id;
						sb.append("" + temp_char);
					}
					else{
						sb.append(this_entity);
					}
				}catch (Exception e) {
					sb.append(this_entity);
				}
			}else{
				String this_result = getResultByName(this_entity);
				if (this_result != null){
					sb.append(this_result);
				}else{
					sb.append(this_entity);
				}
			}
//			last_star_pos = this_start_pos;
			last_end_pos = this_end_pos;
		}
		if (this_end_pos != originString.length()){
			sb.append(new String(originString.substring(this_end_pos)));
		}
		return sb.toString();
	}
}
